/**
 * 
 */
package w83b.iLote4.stubs;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.xml.namespace.QName;
import javax.xml.rpc.handler.HandlerInfo;
import javax.xml.rpc.handler.HandlerRegistry;

import sun.misc.BASE64Decoder;
import w83b.w83bBeans.W83bCertificadoBean;
import w83b.w83bUtilidadesComunes.W83bBase64;
import w83b.w83bUtilidadesComunes.W83bBaseWSInterface;
import w83b.w83bUtilidadesComunes.W83bClsConstantes;
import w83b.w83bUtilidadesComunes.W83bClsTrazas;
import w83b.w83bUtilidadesComunes.W83bDOMUtils;
import w83b.w83bUtilidadesComunes.W83bUtilXml;
import w83b.w83bUtilidadesComunes.W83bWSInterfaceException;
import x43f.ejie.com.X43FNSHF.Body;
import x43f.ejie.com.X43FNSHF.CreateAdESSignature;
import x43f.ejie.com.X43FNSHF.CreateAdESSignatureResponse;
import x43f.ejie.com.X43FNSHF.DatosPersona;
import x43f.ejie.com.X43FNSHF.EjgvDocument;
import x43f.ejie.com.X43FNSHF.EjgvDocumentType;
import x43f.ejie.com.X43FNSHF.FeaType;
import x43f.ejie.com.X43FNSHF.Header;
import x43f.ejie.com.X43FNSHF.SignaturePlacementAnonType4;
import x43f.ejie.com.X43FNSHF.VerificationResultType;
import x43f.ejie.com.X43FNSHF.VerifyAdESSignature;
import x43f.ejie.com.X43FNSHF.VerifyAdESSignatureResponse;

import com.ejie.nshf.client.X43FNSHF;
import com.ejie.nshf.client.X43FNSHF_Impl;
import com.ejie.nshf.client.X43FNSHF_PortType;

import es.ejie.frmk.listeners.base.Q70ListenerUtils;


/**
 * 
 * @author dcarranza
 *
 */
public class W83bNSHFFacadeWS extends W83bBaseWSInterface {

	/**
	 * 
	 * @param sSessionToken token de session
	 * @param sGUID identificador de la tarea
	 * @param sTipoTarea tipo de la tarea
	 * @return String
	 * @throws W83bWSInterfaceException excepcion
	 */
	public String createEjgvDocumentFromXml(String tokenXlnets, String computableXML_b64, String templateXSL_b64) throws W83bWSInterfaceException {
		String [] paramNames = new String[W83bClsConstantes.DOS];
		String [] paramValues = new String[W83bClsConstantes.DOS];
		paramNames[0] = "computableXML_b64";
	
		paramValues[0] =  W83bBase64.encodeString("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"+computableXML_b64);
		
		
		W83bClsTrazas.trazaDebug(null, "computableXML_b64:"+ computableXML_b64);
		paramNames[1] = "templateXSL_b64";
		
			
		paramValues[1] = W83bBase64.encodeString(templateXSL_b64);
		
		W83bClsTrazas.trazaDebug(null, "templateXSL_b64:"+ templateXSL_b64);
		return this.invoke(tokenXlnets,"createEjgvDocumentFromXml", paramNames, paramValues);
	}
	
	/**
	 * 
	 * @param sSessionToken token de session
	 * @param sGUID identificador de la tarea
	 * @param sTipoTarea tipo de la tarea
	 * @return String
	 * @throws W83bWSInterfaceException excepcion
	 */
	public String createEjgvDocumentFromHtml(String computableXML_b64, String htmlDocument_b64) throws W83bWSInterfaceException {
		String [] paramNames = new String[W83bClsConstantes.DOS];
		String [] paramValues = new String[W83bClsConstantes.DOS];
		paramNames[0] = "computableXML_b64";
		paramValues[0] =  W83bDOMUtils.encode(computableXML_b64.getBytes());
		W83bClsTrazas.trazaDebug(null, "computableXML_b64:"+ computableXML_b64);
		paramNames[1] = "htmlDocument_b64";
		paramValues[1] = W83bDOMUtils.encode(htmlDocument_b64.getBytes());
		W83bClsTrazas.trazaDebug(null, "htmlDocument_b64:"+ htmlDocument_b64);
		return this.invoke("createEjgvDocumentFromHtml", paramNames, paramValues);
	}
	
	/**
	 * Devuleve informacion de la firma del ejgvdocument
	 * @param tokenXlnets token de session
	 * @param signature xml de la firma
	 * @return informacion de lafirma
	 * @throws W83bWSInterfaceException
	 */
	public String verifyEjgvDocument(String tokenXlnets,String signature) throws W83bWSInterfaceException{
		return this.invoke("http://com.ejie.x43f/X43FNSHF/",tokenXlnets,"verifyEjgvDocument", "signature", signature);
	}
	
	/**
	 * Valida una firma
	 * @param tokenXlnets token de session
	 * @param signature xml de la firma
	 * @return informacion de lafirma
	 * @throws W83bWSInterfaceException
	 */
	public W83bCertificadoBean verifyAdESSignature(String tokenXlnets,String ejgvFirma,String documentB64) throws Exception{
		String url=(String)this.getWebServiceURL();
		
		
			
		VerifyAdESSignature cr = new VerifyAdESSignature();
		W83bClsTrazas.trazaDebug(null,"W83bNSHFFacadeWS.verifyAdESSignature() url "+url);
		W83bClsTrazas.trazaDebug(null,"W83bNSHFFacadeWS.verifyAdESSignature() ***********************************************************");
		
		
		BASE64Decoder decode= new BASE64Decoder();
		byte[] contenidoBase641= decode.decodeBuffer(documentB64);
		//cr.setDocument_B64(W83BBase64.decode(documentB64));
		cr.setDocument_B64(contenidoBase641);
		String strFirma=W83bUtilXml.fncParsearXml(ejgvFirma, "sign");
		boolean esXadesT=false;
		//Si es la firma del applet, viene en B64, no un ejgvDocument, y es ES-T, no ES-A
		if(strFirma.equals("NOEXISTE")){
			esXadesT=true;
			strFirma=ejgvFirma;
		}
		
		
		if(strFirma.indexOf("<")!=-1){
			strFirma=W83bBase64.encodeString(strFirma);
		}
		
		
		Header header=new Header();
		if(esXadesT){//Si es la firma del applet, viene en B64, no un ejgvDocument, y es ES-T, no ES-A
			header.setFormat("ES-T");
			header.setVersion("2.0");
			header.setIsConservable("1");
			header.setDocumentIsRequired("0");
			header.setFlags("0");
			header.setType("xades");
			header.setPlacement(SignaturePlacementAnonType4._detached);
		}else{
			header.setType(W83bUtilXml.fncParsearXml(ejgvFirma, "type"));
			header.setPlacement(W83bUtilXml.fncParsearXml(ejgvFirma, "placement"));
			header.setFormat(W83bUtilXml.fncParsearXml(ejgvFirma, "format"));
			header.setVersion(W83bUtilXml.fncParsearXml(ejgvFirma, "version"));
			
			if(!W83bUtilXml.fncParsearXml(ejgvFirma, "tsaSerialNumber").equals("NOEXISTE")){
				header.setTsaSerialNumber(W83bUtilXml.fncParsearXml(ejgvFirma, "tsaSerialNumber"));
			}
			
			if(!W83bUtilXml.fncParsearXml(ejgvFirma, "isConservable").equals("NOEXISTE")){
				header.setIsConservable(W83bUtilXml.fncParsearXml(ejgvFirma, "isConservable"));
			}
			
			if(!W83bUtilXml.fncParsearXml(ejgvFirma, "documentIsRequired").equals("NOEXISTE")){
				header.setDocumentIsRequired(W83bUtilXml.fncParsearXml(ejgvFirma, "documentIsRequired"));
			}
			
			header.setFlags(W83bUtilXml.fncParsearXml(ejgvFirma, "flags"));
			
			//Parte fea
			if(!W83bUtilXml.fncParsearXml(ejgvFirma, "fea").equals("NOEXISTE")){
				FeaType fea = new FeaType();
				
				//Datos persona
				DatosPersona datosPersona = new DatosPersona();
				if(!W83bUtilXml.fncParsearXml(ejgvFirma, "datosPersona").equals("NOEXISTE")){
					datosPersona.setApellido1(W83bUtilXml.fncParsearXml(ejgvFirma, "apellido1"));
					datosPersona.setApellido2(W83bUtilXml.fncParsearXml(ejgvFirma, "apellido2"));
					datosPersona.setDni(W83bUtilXml.fncParsearXml(ejgvFirma, "dni"));
					datosPersona.setFnac(W83bUtilXml.fncParsearXml(ejgvFirma, "fnac"));
					datosPersona.setNombre(W83bUtilXml.fncParsearXml(ejgvFirma, "nombre"));
				}
				
				fea.setDatosPersona(datosPersona);
				
				//firma fea
				if(!W83bUtilXml.fncParsearXml(ejgvFirma, "firmaFEA").equals("NOEXISTE")){
					fea.setFirmaFEA(W83bUtilXml.fncParsearXml(ejgvFirma, "firmaFEA"));
				}
				header.setFea(fea);
			}
		}
		
		Body body=new Body();
		body.setSign(strFirma);			
		EjgvDocument ejgvDoc=new EjgvDocument(header,body);
		
		EjgvDocumentType ejgvDocType=new EjgvDocumentType(ejgvDoc);
		
		cr.setSignature(ejgvDocType);
		
		W83bClsTrazas.trazaDebug(null,"W83bNSHFFacadeWS.verifyAdESSignature() EJGVfirma: "+cr.getSignature().toString());
		
		X43FNSHF nshf = new X43FNSHF_Impl(url);
		Iterator i = nshf.getPorts();
		HandlerRegistry registry = nshf.getHandlerRegistry();
		Map map = new HashMap();
		map.put("sessionToken",tokenXlnets);
		List handlerList = new ArrayList();
		handlerList.add( new HandlerInfo( R02FTokenHandler.class, map, null ) );
		registry.setHandlerChain( (QName)i.next(), handlerList );
		
		X43FNSHF_PortType port = nshf.getX43FNSHF_PortType();
		
		VerifyAdESSignatureResponse resp = port.verifyAdESSignature(cr);
		VerificationResultType resultado =resp.getVerifyAdESSignatureResult();
		
		W83bCertificadoBean certificadoBean = new W83bCertificadoBean();
		
		if (!resultado.getVerificationResult().getIsSuccessResult().equalsIgnoreCase("true")){
		//Si no es válido, lanzar una excepción
			certificadoBean.setValido(false);
			W83bClsTrazas.trazaDebug(null,"W83bNSHFFacadeWS.verifyAdESSignature() -La firma no se ha validado. Causa: " + resultado.getVerificationResult().getResultMessage());
			certificadoBean.setCausa(resultado.getVerificationResult().getResultMessage());
		}else{
			certificadoBean.setValido(true);
	
			List issuers=new ArrayList();
			List subjects=new ArrayList();
	
			for(int k=0;k<resultado.getVerificationResult().getSignCertificates().length;k++){
			issuers.add(resultado.getVerificationResult().getSignCertificates()[k].getIssuer());
			subjects.add(resultado.getVerificationResult().getSignCertificates()[k].getSubject());
			}
			certificadoBean.setCertificateIssuer(issuers);
			certificadoBean.setCertificateIssuer(issuers);
			certificadoBean.setCertificateSubject(subjects);
			certificadoBean.setCertificateSerialNumber(resultado.getVerificationResult().getSignCertificates()[0].getSerialNumber());
			certificadoBean.setPolitica(resultado.getVerificationResult().getSignCertificates()[0].getPolicy());
			
			
			if(resultado.getVerificationResult().getSignCertificates()[0].getEntidad()!=null){
				//firma con txartela de entidad
				certificadoBean.setNombre(resultado.getVerificationResult().getSignCertificates()[0].getEntidad().getRepresentante().getNombreCompleto());
				certificadoBean.setDocumento(resultado.getVerificationResult().getSignCertificates()[0].getEntidad().getCif());
			}else if(resultado.getVerificationResult().getSignCertificates()[0].getSuscriptor()!=null){
				//Firma con txartela de ciudadano
				certificadoBean.setNombre(resultado.getVerificationResult().getSignCertificates()[0].getSuscriptor().getNombreCompleto());
				certificadoBean.setDocumento(resultado.getVerificationResult().getSignCertificates()[0].getSuscriptor().getDni());
			}
	
		}
		
		return certificadoBean;
		
	}
	
	
	/**
	 * Devuleve informacion de la firma del ejgvdocument
	 * @param tokenXlnets token de session
	 * @param signature xml de la firma
	 * @return informacion de lafirma
	 * @throws W83bWSInterfaceException
	 */
	public String createHashByteArray  (String tokenXlnets,String documentB64) throws W83bWSInterfaceException{
		return this.invoke("http://com.ejie.x43f/X43FNSHF/",tokenXlnets,"createHashByteArray", "document_b64", documentB64);
	}
	
	
	/**
	 * Devuleve la firma del ejgvdocument
	 * @param tokenXlnets token de session
	 * @param certificado certificado que firma
	 * @return notificacionB64 notificación que firma
	 * @throws W83bWSInterfaceException
	 */
	public String createAdESSignature  (String tokenXlnets,String certificado, String notificacionB64) throws Exception{
		String url=(String)this.getWebServiceURL();
		
		CreateAdESSignature createAdESSignature = new CreateAdESSignature();
		W83bClsTrazas.trazaDebug(null,"W83bNSHFFacadeWS.createAdESSignature() url "+url);
		W83bClsTrazas.trazaDebug(null,"W83bNSHFFacadeWS.createAdESSignature() ***********************************************************");


		//Certificado
		createAdESSignature.setCertificateId(certificado);
		
		//Notificacion
		BASE64Decoder decode= new BASE64Decoder();
		byte[] contenidoBase641= decode.decodeBuffer(notificacionB64);
		createAdESSignature.setDocument_B64(notificacionB64.getBytes());

		//signaturePlacement
		createAdESSignature.setSignaturePlacement(SignaturePlacementAnonType4.enveloped);
		
		X43FNSHF nshf = new X43FNSHF_Impl(url);
		Iterator i = nshf.getPorts();
		HandlerRegistry registry = nshf.getHandlerRegistry();
		Map map = new HashMap();
		map.put("sessionToken",tokenXlnets);
		List handlerList = new ArrayList();
		handlerList.add( new HandlerInfo( R02FTokenHandler.class, map, null ) );
		registry.setHandlerChain( (QName)i.next(), handlerList );
		
		X43FNSHF_PortType port = nshf.getX43FNSHF_PortType();
		CreateAdESSignatureResponse resp = port.createAdESSignature(createAdESSignature);
		EjgvDocumentType resultado =resp.getCreateAdESSignatureResult();

		
		
		return resultado.getEjgvDocument().getBody().getSign();
	}

	
	/**
	 * @return String
	 */
	protected String getWebServiceURL() {
		return Q70ListenerUtils.getApplicationProperty("JWS.NSHFFACADE");
	}
	
	
}